﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration.Install;
using System.ComponentModel;
using System.IO;
using Microsoft.Win32;
using System.Collections;
using Gauss.Isp;

namespace MPI.NETTemplateInstallHelper
{
    [RunInstaller(true)]
    public partial class Installer : System.Configuration.Install.Installer
    {
        private readonly string TEMPLATE_FILE = "MPI.NET Template.zip";

        //installContext //installContext;

        public Installer()
        {
        }

        private string GetVSInstallPath()
        {
            RegistryKey visStudio = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\10.0");
            string visStudioPath;
            if (visStudio == null)
            {
                visStudio = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\VisualStudio\10.0_Config");
                //try to find it on system
                visStudioPath = @"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\";
                if (!File.Exists(visStudioPath))
                {
                    visStudioPath = @"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\";
                    if (!File.Exists(visStudioPath))
                    {
                        return string.Empty;
                    }
                }
            }
            else
            {
                visStudioPath = visStudio.GetValue("InstallDir") as string;
                if (visStudioPath == null)
                {
                    return string.Empty;
                }
            }
            return visStudioPath;
        }

        public override void Install(IDictionary stateSaver)
        {
            //installContext = new //installContext(
                      //Path.Combine(this.Context.Parameters["InstallPath"], "MPI.NETTemplateInstall.log"), null);

            bool errors = false;

            base.Install(stateSaver);

            stateSaver.Remove("InstalledTemplate");
            //from CustomActionData
            string installPath = this.Context.Parameters["InstallPath"];

            string visStudioPath = GetVSInstallPath();
            if (visStudioPath == string.Empty)
            {
                //installContext.LogMessage("Could not find Visual Studio 2010 installation");
                return;
            }

            string dest = Path.Combine(visStudioPath, @"ProjectTemplates\csharp");
            try
            {
                File.Move(Path.Combine(installPath, TEMPLATE_FILE), Path.Combine(dest, TEMPLATE_FILE));
            }
            catch (Exception e)
            {
                //installContext.LogMessage("Unable to remove MPI.NET Template: " + e.Message);
                errors = true;
            }
            if (!errors)
            {
                try
                {
                    ExecuteVSSetup(visStudioPath); //this rebuilds the ProjectTemplates cache
                }
                catch (Exception e)
                {
                    //installContext.LogMessage("Problem refreshing Visual Studio project template cache for MPI.NET template -- " +
                       // "Please execute devenv.exe /setup: "
                        //+ e.Message);
                }
                stateSaver.Add("InstalledTemplate", true);
            }
        }

        private void ExecuteVSSetup(string VSInstPath)
        {
            using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
            {
                proc.StartInfo.FileName = Path.Combine(VSInstPath, "devenv.exe");
                proc.StartInfo.Arguments = "/setup";
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.CreateNoWindow = true;
                proc.Start();
                try
                {
                    proc.WaitForExit(int.MaxValue - 1);
                }
                catch (System.Threading.ThreadAbortException)
                {
                    KillProcess.TerminateProcessTree(proc.Handle, (uint)proc.Id, 255);
                    throw;
                }
                finally
                {
                    while (!proc.HasExited)
                    {
                        proc.WaitForExit(500);
                    }
                    KillProcess.TerminateProcessTree(proc.Handle, (uint)proc.Id, 255);
                }
            }
        }

        public override void Uninstall(IDictionary savedState)
        {
            //installContext = new //installContext(
                      //Path.Combine(this.Context.Parameters["InstallPath"], "MPI.NETTemplateInstall.log"), null);

            bool errors = false;

            base.Uninstall(savedState);

            if(!savedState.Contains("InstalledTemplate")){
                return;
            }

            string vsPath = GetVSInstallPath();
            if (vsPath == string.Empty)
            {
                //installContext.LogMessage("Could not find Visual Studio 2010 installation");
                return;
            }

            try
            {
                File.Delete(Path.Combine(vsPath, @"ProjectTemplates\CSharp", TEMPLATE_FILE));
            }
            catch (Exception e)
            {
                //installContext.LogMessage("Unable to remove MPI.NET template file: " + e.Message);
                errors = true;
            }

            if (!errors)
            {
                try
                {
                    ExecuteVSSetup(vsPath);
                }
                catch (Exception e)
                {
                    //installContext.LogMessage("Unable to refresh project template cache when removing " +
                        //"MPI.NET template -- run devenv.exe /setup: " +
                        //e.Message);
                }
                savedState.Remove("InstalledTemplate");
            }
        }
    }
}
